package com.seecoder.BlueWhale.serviceImpl;

import com.seecoder.BlueWhale.enums.RoleEnum;
import com.seecoder.BlueWhale.exception.BlueWhaleException;
import com.seecoder.BlueWhale.po.Store;
import com.seecoder.BlueWhale.po.User;
import com.seecoder.BlueWhale.repository.StoreRepository;
import com.seecoder.BlueWhale.repository.UserRepository;
import com.seecoder.BlueWhale.service.UserService;
import com.seecoder.BlueWhale.util.SecurityUtil;
import com.seecoder.BlueWhale.util.TokenUtil;
import com.seecoder.BlueWhale.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * @Author: GaoZhaolong
 * @Date: 14:46 2023/11/26
 *
 * 注册登录功能实现
*/
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    UserRepository userRepository;
    
    @Autowired
    TokenUtil tokenUtil;

    @Autowired
    SecurityUtil securityUtil;

    @Autowired
    StoreRepository storeRepository;


    @Override
    public Boolean register(UserVO userVO) {
        User user = userRepository.findByPhone(userVO.getPhone());
        if (user != null) {
            throw BlueWhaleException.phoneAlreadyExists();
        }
        //用户注册时必须传入其身份
        if (userVO.getRole() == null) {
            throw BlueWhaleException.notChooseRole();
        }
        //注册上店员时必须传入所属商店ID
        if (userVO.getRole() == RoleEnum.STAFF && userVO.getStoreId() == null) {
            throw BlueWhaleException.notChooseStoreID();
        }
        User newUser = userVO.toPO();
        newUser.setPassword(SecurityUtil.encryptSha256(newUser.getPassword()));
        newUser.setCreateTime(new Date());
        userRepository.save(newUser);
        log.warn("User[{}] register successfully", newUser.getPhone());
        return true;
    }

    @Override
    public String login(String phone, String password) {
        password = SecurityUtil.encryptSha256(password);
        User user = userRepository.findByPhoneAndPassword(phone, password);
        if (user == null) {
            throw BlueWhaleException.phoneOrPasswordError();
        }
        log.warn("User[{}] login successfully", user.getPhone());
        return tokenUtil.getToken(user);
    }

    //这个函数的修改主要是为了返回时带上店员所属商店名称（前端的合理需求）
    //由于数据库中没有存放商店名称，所以这里需要额外处理一下
    //注意，与前端交互的数据类型应该是xxxVO
    @Override
    public UserVO getInformation() {
        User user=securityUtil.getCurrentUser();
        return getInfo(user);
    }

    @Override
    public UserVO getInformation(int id) {
        User user = userRepository.findById(id);
        return getInfo(user);
    }

    @Override
    public Boolean updateInformation(UserVO userVO) {
        User user=securityUtil.getCurrentUser();
        if (user == null) {
            throw BlueWhaleException.cannotFindUser();
        }
        if (userVO.getPassword()!=null){
            user.setPassword(SecurityUtil.encryptSha256(userVO.getPassword()));
        }
        if (userVO.getName()!=null){
            user.setName(userVO.getName());
        }
        if (userVO.getAddress()!=null){
            user.setAddress(userVO.getAddress());
        }
        userRepository.save(user);
        return true;
    }

    /** 提供目标用户的信息
     * @param user 目标用户
     * @return 包装后的UserVO
     */
    private UserVO getInfo(User user) {
        if (user == null) {
            throw BlueWhaleException.cannotFindUser();
        }
        return wrapSN(user.toVO());
    }

    /**
     * 为用户包装商店名称(Store Name)
     * @param userVO 待包装的UserVO
     * @return 包装后的UserVO
     */
    private UserVO wrapSN(UserVO userVO) {
        Store curStore;
        if (userVO.getStoreId() != null) {
            curStore = storeRepository.findById(userVO.getStoreId().intValue());
            if (curStore == null) {
                throw BlueWhaleException.cannotFindStore();
            }
        }
        return userVO;
    }

}
